package com.huike.clues.MpService.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huike.clues.MpMapper.MpSysMenuMapper;
import com.huike.clues.MpMapper.MpSysRoleIdMapper;
import com.huike.clues.MpMapper.MpSysRoleMenuMapper;
import com.huike.clues.MpService.MpSysMenuService;
import com.huike.clues.domain.dto.MPSysMenuDTO;
import com.huike.clues.domain.dto.MPSysMenuTreeDTO;
import com.huike.clues.domain.vo.MPSysMenuFindByIdVo;
import com.huike.clues.domain.vo.MPSysMenuTreeChildrenVo;
import com.huike.clues.domain.vo.MPSysMenuTreeVo;
import com.huike.clues.domain.vo.RoleMenuTreeAjaxResultVo;
import com.huike.common.core.domain.TreeSelect;
import com.huike.common.core.domain.model.LoginUser;
import com.huike.common.entity.MPSysMenu;
import com.huike.common.entity.MPSysRoleMenu;
import com.huike.common.getUserId.TokenService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;

@Service
@Slf4j
public class MpSysMenuServiceImpl extends ServiceImpl<MpSysMenuMapper, MPSysMenu> implements MpSysMenuService {

    @Autowired
    private MpSysMenuMapper mpSysMenuMapper;
    @Autowired
    private MpSysRoleIdMapper mpSysRoleIdMapper;

    @Autowired
    private MpSysRoleMenuMapper mpSysRoleMenuMapper;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private HttpServletRequest request;

    /**
     * 新增菜单
     * @param mpSysMenuDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(MPSysMenuDTO mpSysMenuDTO) {
        MPSysMenu menu = new MPSysMenu();
        BeanUtils.copyProperties(mpSysMenuDTO, menu);
        menu.setCreateTime(LocalDateTime.now());
        menu.setUpdateTime(LocalDateTime.now());
        // TODO 缺少更新人，创建人
        mpSysMenuMapper.insert(menu);
        for (MPSysMenu child : mpSysMenuDTO.getChildren()) {
            BeanUtils.copyProperties(child, menu);
            mpSysMenuMapper.insert(menu);
        }
    }

    /**
     * 根据菜单编号获取详细信息
     *
     * @param menuId
     * @return
     */
    @Override
    public MPSysMenuFindByIdVo menuFindById(Long menuId) {
        MPSysMenu mpSysMenu = mpSysMenuMapper.selectById(menuId);
        LambdaQueryWrapper<MPSysMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MPSysMenu::getParentId, mpSysMenu.getParentId());
        List<MPSysMenu> children = mpSysMenuMapper.selectList(wrapper);
        MPSysMenuFindByIdVo mpSysMenuFindByIdVo = new MPSysMenuFindByIdVo();
        BeanUtils.copyProperties(mpSysMenu, mpSysMenuFindByIdVo);
        mpSysMenuFindByIdVo.setChildren(children);
        return mpSysMenuFindByIdVo;
    }

    /**
     * 删除菜单
     *
     * @param menuId
     */
    @Override
    public void menuDeleteById(Long menuId) {
        MPSysMenu menu = mpSysMenuMapper.selectById(menuId);

        /*MPSysMenuFindCount mpSysMenuFindCount = new MPSysMenuFindCount();
        BeanUtils.copyProperties(menu,mpSysMenuFindCount);*/
        QueryWrapper<MPSysMenu> wrapper = new QueryWrapper<>();
        wrapper.select("count(*) as count");
        wrapper.eq("parent_id", menuId);
        wrapper.groupBy("parent_id");
        List<Map<String, Object>> maps = mpSysMenuMapper.selectMaps(wrapper);
        if(!CollectionUtils.isEmpty(maps))
            throw new RuntimeException("包含子目录不能删除");
        /*for (String s : maps.get(0).keySet()) {
            if (Objects.equals(s, "count")) {
                Map<String, Object> map = maps.get(0);
                Integer number = Integer.parseInt(map.get("count").toString());
                if (number > 0) {

                }
            }
        }*/
        mpSysMenuMapper.deleteById(menuId);
    }

    /**
     * 获取菜单下拉树列表
     * @param mpSysMenuTreeDTO
     * @return
     */
    @Override
    public List<MPSysMenuTreeVo> treeselect(MPSysMenuTreeDTO mpSysMenuTreeDTO) {
        //获取主菜单数据
        LambdaQueryWrapper<MPSysMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(null != mpSysMenuTreeDTO.getMenuName(),MPSysMenu::getMenuName,mpSysMenuTreeDTO.getMenuName());
        wrapper.eq(null != mpSysMenuTreeDTO.getMenuType(),MPSysMenu::getMenuType,mpSysMenuTreeDTO.getMenuType());
        wrapper.eq(null != mpSysMenuTreeDTO.getOrderNum(),MPSysMenu::getOrderNum,mpSysMenuTreeDTO.getOrderNum());
        wrapper.eq(MPSysMenu::getParentId,0);
        List<MPSysMenu> menus = mpSysMenuMapper.selectList(wrapper);
        //定义返回对象集合
        List<MPSysMenuTreeVo> menuTreeVoList = new ArrayList<>();

        //遍历查询结果
        if(CollectionUtils.isEmpty(menus))
            throw new RuntimeException("获取请求信息失败");


        for (MPSysMenu menu : menus) {
            MPSysMenuTreeVo mpSysMenuTreeVo = new MPSysMenuTreeVo();
            mpSysMenuTreeVo.setId(menu.getMenuId());
            mpSysMenuTreeVo.setLabel(menu.getMenuName());

            LambdaQueryWrapper<MPSysMenu> wrapperChildren = new LambdaQueryWrapper<>();
            wrapperChildren.eq(MPSysMenu::getParentId,menu.getMenuId());
            List<MPSysMenu> menusChildren = mpSysMenuMapper.selectList(wrapperChildren);
            for (MPSysMenu menusChild : menusChildren) {
                MPSysMenuTreeChildrenVo mpSysMenuTreeChildrenVo = new MPSysMenuTreeChildrenVo();
                mpSysMenuTreeChildrenVo.setId(menusChild.getMenuId());
                mpSysMenuTreeChildrenVo.setLabel(menusChild.getMenuName());

                /*LambdaQueryWrapper<MPSysMenu> wrapperChildrenChildren = new LambdaQueryWrapper<>();
                wrapperChildren.eq(MPSysMenu::getParentId,menusChild.getMenuId());
                List<MPSysMenu> menusChildrenChildren = mpSysMenuMapper.selectList(wrapperChildrenChildren);

                for (MPSysMenu menusChildrenChild : menusChildrenChildren) {
                    MPSysMenuTreeChildrenVo mpSysMenuTreeChildrenVo1 = new MPSysMenuTreeChildrenVo();
                    mpSysMenuTreeChildrenVo1.setId(menusChildrenChild.getMenuId());
                    mpSysMenuTreeChildrenVo1.setLabel(menusChildrenChild.getMenuName());
                    mpSysMenuTreeChildrenVo.get
                }*/

                mpSysMenuTreeVo.getChildren().add(mpSysMenuTreeChildrenVo);
            }
            menuTreeVoList.add(mpSysMenuTreeVo);
        }
        return menuTreeVoList;
    }

    /**
     * 加载对应角色菜单列表树
     * @param roleId
     * @return
     */
    @Override
    public RoleMenuTreeAjaxResultVo roleMenuTreeselect(Long roleId) {
        //查询所有的meusID
        QueryWrapper<MPSysRoleMenu> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id",roleId);
        List<MPSysRoleMenu> roleList = mpSysRoleMenuMapper.selectList(wrapper);
        List<Long> checkedKeys = new ArrayList<>();
        List<TreeSelect> menus = new ArrayList<>();
        RoleMenuTreeAjaxResultVo roleMenuTreeAjaxResultVo = new RoleMenuTreeAjaxResultVo();
        for (MPSysRoleMenu mpSysRoleMenu : roleList) {
            checkedKeys.add(mpSysRoleMenu.getMenuId());
            //查询当前菜单的子菜单
            TreeSelect treeSelect = treeSelect(mpSysRoleMenu.getMenuId());
            menus.add(treeSelect);
        }
        roleMenuTreeAjaxResultVo.setCheckedKeys(checkedKeys);
        roleMenuTreeAjaxResultVo.setMenus(menus);
        roleMenuTreeAjaxResultVo.setCode(200);

        return roleMenuTreeAjaxResultVo;
    }

    /**
     * 递归查询子菜单
     */
    public TreeSelect treeSelect(Long id){
        //LambdaQueryWrapper<MPSysMenu> wrapper = new LambdaQueryWrapper<>();
        //wrapper.eq(MPSysMenu::getMenuId,id);
        //List<MPSysMenu> roleList = mpSysMenuMapper.selectList(wrapper);
        MPSysMenu menu = mpSysMenuMapper.selectById(id);
        if(ObjectUtils.isEmpty(menu))
            return null;
        //查询id列表
        TreeSelect treeSelect = new TreeSelect();
        /*treeSelect.setId(menu.getMenuId());
        treeSelect.setLabel(menu.getMenuName());*/
        if(menu.getParentId() == 0){
            treeSelect.setId(menu.getMenuId());
            treeSelect.setLabel(menu.getMenuName());

            return treeSelect;
        }
        LambdaQueryWrapper<MPSysMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MPSysMenu::getMenuId,menu.getParentId());
        List<MPSysMenu> roleList = mpSysMenuMapper.selectList(wrapper);
        if(CollectionUtils.isEmpty(roleList))
            return treeSelect;
        TreeSelect treeSelect1 = null;
        for (MPSysMenu mpSysMenu : roleList) {
            Long menuId = mpSysMenu.getMenuId();
            treeSelect = treeSelect(menuId);
            treeSelect.setId(mpSysMenu.getMenuId());
            treeSelect.setLabel(mpSysMenu.getMenuName());
        }
        treeSelect.getChildren().add(treeSelect1);
        return treeSelect;
    }

    /**
     * 修改菜单
     * @param mpSysMenuDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMenu(MPSysMenuDTO mpSysMenuDTO) {
        LoginUser loginUser = tokenService.getLoginUser(request);
        Long userId = loginUser.getUser().getUserId();

        MPSysMenu mpSysMenu = new MPSysMenu();
        BeanUtils.copyProperties(mpSysMenuDTO,mpSysMenu);
        mpSysMenu.setUpdateTime(LocalDateTime.now());
        mpSysMenu.setUpdateBy(loginUser.getUsername());
        mpSysMenuMapper.updateById(mpSysMenu);
    }
}
